/**
 * BudgetBuoy
 * 
 * Simplify your personal expense management
 * 
 * @team cs2103jan13-w15-3j
 */

//--------------------------------------------------------------

/**
 * CLI Class
 * 
 * Description: Main Class of BudgetBuoy 
 * 
 * 
 * @package cli
 * @author Lai Yong Quan (A0080909Y)
 * @co-author Tan Si Ling (A0085314J) (for 1 method only)
 */


//@author A0080909Y
/*by Lai Yong Quan unless otherwise stated
 */

package cli;

import logic.API;
import shared.*;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

import cli.menu.Function;
import cli.menu.State;
import cli.tools.Action;
import cli.tools.Tools;


public class CLI implements IOInterface{


	protected final static int entriesPerPage = 10;
	protected final static SimpleDateFormat sdf  = new SimpleDateFormat("dd.MM.yyyy");
	protected final static DateFormat dateFormat = sdf;
	protected final static char[] HOTKEYS = {'b','B','u','U','h','H','r','R'};
	protected static Calendar currentDate = new GregorianCalendar();
	protected static API api = new API();  //for use in the Action.java
	protected final static Action action = new Action(api);
	protected static Scanner sc = new Scanner(System.in);
	protected static boolean debug = false;

	public CLI(){
		currentDate = new GregorianCalendar();
		API api = new API();  //for use in the Action.java
		sc = new Scanner(System.in);
		debug = false;
		//cli = this;
	}

	public   API getApi(){
		return api;
	}

	public int getEntriesPerPage(){
		return entriesPerPage;
	}

	public DateFormat getDateFormat(){
		return dateFormat;
	}

	public Action getAction(){
		return action;
	}

	public char[] getHotkeys(){
		return HOTKEYS;
	}

	public boolean getDebug(){
		return debug;
	}

	// implemented by : Si Ling
	public   void checkAlert() {


		int currentBal;
		/**
		 * Get the thresholds. if the currentBal is greater than the warningBal
		 * a warning is given.
		 */
		int warningBal, daysToPayment;

		println("Checking for alerts....");

		ArrayList<Loan> loanList = api.getLoanList();

		currentBal = api.getBalance(); // get the curr balance
		warningBal = api.getMinBalance();
		daysToPayment = api.getDaysToPayment();

		if (debug) {
			println("Current balance: " + currentBal);
			println("warningBal " + warningBal);
		}

		if (warningBal >= currentBal) {
			println("**** Warning ****");
			printf("Your Current Balance is: $%.2f\n" , ((double)currentBal)/100.00);
			if (currentBal < 0)
				println("You're in the RED!");
			else if (currentBal == 0)
				System.out
				.println("You're tipping over...\nNow now, no impulsive purchases...");
			println("*****************");
		} else {
			println("All green :)");
		}

		int counter = 0;
		boolean onePaymentForThisLoan;
		// run the Loanlist provided see if anything is due soon
		for (int i = 0; i < loanList.size(); i++) {

			onePaymentForThisLoan = true;
			LinkedList<Payment> futurePaymentList = loanList.get(i)
					.getFuturePayments();
			for (int j = 0; j < futurePaymentList.size(); j++)
				if (futurePaymentList.get(j).getYear() == currentDate.get(Calendar.YEAR)) {

					/**
					 * Compute days to payment Difference in dates Adapted from
					 * StackOverflow and edited by Si Ling
					 */

					Calendar start = Calendar.getInstance(); // time and date
					// right now
					Calendar end = Calendar.getInstance();

					end.set(futurePaymentList.get(j).getYear(),
							(futurePaymentList.get(j).getMonth()- 1), //+1 because month is 0-based
							futurePaymentList.get(j).getDay()); //set the end date of the payment
					Date startDate = start.getTime();
					Date endDate = end.getTime();
					long startTime = startDate.getTime();
					long endTime = endDate.getTime();
					long diffTime = endTime - startTime;
					long diffDays = diffTime / (1000 * 60 * 60 * 24);

					String dateToPay = futurePaymentList.get(j).getDay()+"."+futurePaymentList.get(j).getMonth()
							+"."+futurePaymentList.get(j).getYear() ;
					if ((int) diffDays <= daysToPayment) {

						if (onePaymentForThisLoan) {
							if(counter == 0){
								println("======>>Alert<<======");
								println("Your loan is due soon...");
								println("   [Loan]         [Date of Payment]         [Amt due]");
							}

							if(counter<=4){  //if there is 5 or less payment due, print them
								String loanName= loanList.get(i).getName()+"            ";
								loanName = loanName.substring(0,12); //ensure that the loan name 
																	 //is less than 12 characters
								
								String dateLoan = dateToPay+"          ";
								dateLoan = dateLoan.substring(0,9); //ensure that it occupies at most 9 char
								
								counter++;
								println("#" + counter +" "+ loanName
										+"     " + dateLoan+"                "+loanList.get(i).getAmt()/100.00);  
							}

							else{  //else just increment the counter
								counter++;
							}

							onePaymentForThisLoan = false;
							
						}
						
						//if there is other payment dues for the same loan we dont print it in main screen
						//else {   
						//	println("   nxt date dues: "
						//			+ futurePaymentList.get(j).getDateString());
						//}
					}
				}
		}
		if(counter> 5){
			println("    and"+(counter-5)+"more payments due");
		}
		println("=====================");
	}

	// **END**

	public void terminate(){
		sc.close();
		try {
			println("BudgetBuoy is terminating");
			println("Saving changes...");
			api.save();
			println("Saved");
			println("Have a nice day!");
			System.exit(0);
		} catch (Exception e) {
			this.println("BudgetBuoy was unable to save your changes");
			this.print(e.getMessage());
		}

	}

	public String nextLine() {
		String input = null;
		while(input == null){
			input = sc.nextLine();
		}
		return input;
	}

	public void print(String toPrint) {
			System.out.print(toPrint);
	}

	public void print(String[] toPrint){
		for(String s: toPrint)
			System.out.println(s);
	}

	public void println(String toPrint){
		System.out.println(toPrint);
	}

	public void println(){
		System.out.println();
	}

	// to seperate updates
	public void clearScreen(){
		String clear = "\n\n\n"; //\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
		print(clear);
	}


	public void printf(String toPrint, double num){
		System.out.printf(toPrint, num);
	}

	@Override
	public int nextInt() throws Exception {
		return sc.nextInt();
	}

	@Override
	public void printf(String toPrint, Object... args) {
		// TODO Auto-generated method stub

	}

	@Override
	 public void runUI() {
		  CLI cli = this;
		  if (debug)
		   cli.println("Running platform: "
		     + System.getProperty("os.name"));
		  // init
		  cli.println("BudgetBuoy v0.02 is loading...");  
		 
		  // init CLI
		  try {
			CommandParser cmdParser = new CommandParser(this);
		   Tools tools = new Tools(cli);
		   //sets a static CLI to all menus (which extend Function)
		   Function.initFunction(cli,tools,cmdParser);
		   api.init();
		   cli.println("Loaded");
		   cli.checkAlert();
		   // println("Alerts checked");
		   State current = State.MAINMENU;
		   State nextState;
		   
		   //loop for menus
		   while(true){
		   nextState = current.run();
		   api.save();
		   current = nextState;
		   //clearScreen();
		   }
		  
		  }
		  catch(Exception e){
		   cli.println("System experienced a point of failure:");
		   cli.print(e.getMessage()+ "\n");
		   e.printStackTrace();
		   cli.println("Terminating...");
		  }
		  
		 }
	

}
